/*
*    Phantom v2.0 GUI Automation Software
*    Copyright (C) 2009  John C. Van Arsdall (john@phantomtest.com)
*
*    This program is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License along
*    with this program; if not, write to the Free Software Foundation, Inc.,
*    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
// Variable.h: interface for the CVariable class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_VARIABLE_H__AF13A5DB_D56F_4758_A4F3_15C3C8A9AED2__INCLUDED_)
#define AFX_VARIABLE_H__AF13A5DB_D56F_4758_A4F3_15C3C8A9AED2__INCLUDED_

#include "ssi_ptrarray.h"	// Added by ClassView
#include "ssi_string.h"	// Added by ClassView
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <list>
#include <iterator>
using std::list;
using std::iterator;


#include "ssi_status.h"	// Added by ClassView

// Add a get_current_variable type thing
// Set the SetData to check the current array state
// after each call, reset the array state
// Should the == copy the index state?
// How about copy constructor?
// Also need to check the <<
// Need a GetIndex
// Need a SetIndex

// Perhaps should have a CVariable List for structures??
// Then what about a CFunction List??  It has to be a user function...

// OK, for now, we will just worry about arrays...

// OK, I have come to the conclusion that arrays should be handled
//   within the CVariable class (this includes multi-dimensional
//   arrays).  Structures and Classes (dare I?) should be specially
//   created subclasses of CData so they can have all the advantages
//   of CData and CVariable.  Perhaps CData should include a pure-
//   virtual function to handle CVariable arrays and CFunctionDecl
//   arrays, with normal data types returning an error?  Or perhaps
//   the default implementation should return the error.  Remember,
//   the more robust you make CData (and CVariable), the easier
//   expansion will be.
//
//   Arrays will be handled through a specially designed nodal
//   structure.  Perhaps we can avoid the current index issue 
//   all together??  Or perhaps not.  It would be best if we could.


//////////----------------------------------------///////////////////
//            MAJOR PROBLEM WITH ARRAYS  
//////////----------------------------------------///////////////////
//  Arrays dont set (or get) data correctly:
//    s[0][0] sets OK
//    s[1][0] will overwrite s[0][1]
//    try a 2 X 2 and get the data... the anomaly will present itself
//  Also... attempt to get beyond array dimension will crash!!!
//  ----> OK now?
//////////----------------------------------------///////////////////

//////////////////////////////////////////////////////////////////////
//
//  Now, need to add array size checking *only* for rvalues (right hand side)
//    - And need to add script capabilty in prep for functions, classes, 
//      structs, flow control
//
//////////////////////////////////////////////////////////////////////

class CData;
class CDataArray;

#define PDATA CData*

class SSI_SCRIPTDLL_API CVariable  
{

public:
	CVariable& CopyVariable(CVariable& In);
	CVariable GetWorkingVariable();
	CData& GetWorkingData();
	CStatus SetWorkingData(CData* In);
	DimNode GetWorkingNode();
	void SetWorkingNode(DimNode New);
	SSI_INT64 GetNumElems();
	void SetType(SSI_INT64 NewType);

	void CopyAllData(CVariable& In);
	
	//static SSI_BOOL CheckCompatibility(SSI_INT64 Type1, SSI_INT64 Type2);
	static SSI_INT64 TypeFromString(const String& S);
	CVariable(const CVariable& Other);

  CData& Get(DimNode Dim = 0);
	CData* Get(SSI_INT64 Ind);
	CData* NewData();

  CStatus SetData(const String& sData, DimNode Dim = SSI_NULL);
	CStatus SetData(CData* aData, DimNode Dim = SSI_NULL);

  String GetTypeString();
  SSI_INT64 GetType();
	
  String Name;
	CVariable();
	virtual ~CVariable();
  SSI_BOOL operator ==(const CVariable &Other);
  virtual CVariable& operator =(CVariable &Other);
  virtual bool operator<(const CVariable& Other) const;
  CVariable& operator<<(CData* Data /*DataArray& In*/);
  CVariable& operator<<(CVariable &Var);
	operator PDATA();
  operator int();
	void ResetArray(CDataArray* New);


private:
//  SSI_INT64 WorkingIndex;
	void copyData(CData* In);
  SSI_INT64 Type;
  DimNode WorkingNode;
  CDataArray* array;


protected:
public:
	CData* GetNextData(DimNode& Dim, SSI_BOOL &EOL, SSI_BOOL bReset = 0, SSI_BOOL bIncludeNULLs = 0);
	SSI_INT64 Flags;
	SSI_CHAR Access;
	DimNode GetDims(void);
};


typedef list<CVariable> VarTree;
typedef list<CVariable>::iterator VarItor;

//typedef list<CVariable> VarTree;
//typedef list<CVariable>::iterator VarItor;

//typedef TNodeTree<CVariable> VarTree;
//typedef TNode<CVariable> VarNode;


#endif // !defined(AFX_VARIABLE_H__AF13A5DB_D56F_4758_A4F3_15C3C8A9AED2__INCLUDED_)



